package com.ctlele.team.space.activity.impl;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSON;
import com.ctlele.team.space.R;
import com.ctlele.team.space.activity.BaseActivity;
import com.ctlele.team.space.adapter.FileItemAdapter;
import com.ctlele.team.space.api.Api;
import com.ctlele.team.space.api.ApiStatusCode;
import com.ctlele.team.space.api.Apis;
import com.ctlele.team.space.entity.vo.FileItemVo;
import com.ctlele.team.space.entity.vo.FileTypeVo;
import com.ctlele.team.space.entity.vo.resp.FileListResp;
import com.ctlele.team.space.util.FileTypeUtils;
import com.ctlele.team.space.util.InputStreamUtils;
import com.ctlele.team.space.util.UriUtils;
import com.ctlele.team.space.widget.dialog.ImageDialog;
import com.ctlele.team.space.widget.dialog.MsgDialog;
import com.ctlele.team.space.widget.toast.IToast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.scwang.smart.refresh.footer.BallPulseFooter;
import com.scwang.smart.refresh.header.MaterialHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.yanzhenjie.permission.AndPermission;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;

import okhttp3.Call;
import okhttp3.Response;

public class FileReceiverActivity extends BaseActivity {

    private static final String TAG = "FileReceiverActivity";

    @Override
    protected int initLayout() {
        return R.layout.activity_file_receiver;
    }

    /**
     * 当前目录
     */
    private final Stack<String> currentDir = new Stack<>();

    /**
     * 当前数据页
     */
    private final AtomicInteger mPage = new AtomicInteger(1);

    /**
     * 数据页大小
     */
    private static final int PAGE_LIMIT = 10;

    /**
     * 返回上一级
     */
    private FloatingActionButton mReturnDir;

    /**
     * 上传到此
     */
    private FloatingActionButton mUploadHere;

    private RecyclerView mRecyclerView;

    private SmartRefreshLayout mSmartRefreshLayout;

    private FileItemAdapter mAdapter;

    private Uri mShareFileUri;

    private String mShareFileType;

    {
        // 根目录
        currentDir.push("0");

        if (!FileTypeUtils.INIT) {
            FileTypeUtils.init(getContext());
        }
    }

    private enum DataOperation {
        load, refresh
    }

    @Override
    protected void initView() {
        mReturnDir = findViewById(R.id.return_dir);
        mUploadHere = findViewById(R.id.upload_here);
        mRecyclerView = findViewById(R.id.file_list);
        mSmartRefreshLayout = findViewById(R.id.refresh_layout);
        mAdapter = new FileItemAdapter(this);
    }

    @Override
    protected void initData() {
        Intent intent = getIntent();
        String action = intent.getAction();
        String type = intent.getType();
        if (Intent.ACTION_SEND.equals(action)) {
            mShareFileUri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM);
            mShareFileType = type;
        } else {
            IToast.fail(getContext(), "文件分享失败").andOnUiThread(this::onBackPressed);
            return;
        }
        bindingEvent();
        // 页面加载时初始化数据
        getFileList(FileReceiverActivity.DataOperation.refresh);
    }

    private void bindingEvent() {
        mAdapter.setOnDirClick((item) -> {
            currentDir.push(item.getDocId());
            getFileList(FileReceiverActivity.DataOperation.refresh);
        });
        mAdapter.setAfterDelete(() -> getFileList(DataOperation.refresh));
        mRecyclerView.setAdapter(mAdapter);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);

        mSmartRefreshLayout.setRefreshHeader(new MaterialHeader(this));
        mSmartRefreshLayout.setRefreshFooter(new BallPulseFooter(this));
        mSmartRefreshLayout.setOnRefreshListener((refresher) -> {
            mPage.set(1);
            getFileList(FileReceiverActivity.DataOperation.refresh);
        });
        mSmartRefreshLayout.setOnLoadMoreListener((refresher) -> {
            mPage.incrementAndGet();
            getFileList(FileReceiverActivity.DataOperation.load);
        });

        mReturnDir.setOnClickListener(view -> {
            if ("0".equals(currentDir.peek())) {
                IToast.alert(getContext(), "当前处于根目录");
            } else {
                if (!"0".equals(currentDir.peek())) {
                    currentDir.pop();
                }
                getFileList(FileReceiverActivity.DataOperation.refresh);
            }
        });

        mUploadHere.setOnClickListener(view -> {
            if (mShareFileUri == null) {
                IToast.fail(getContext(), "文件分享失败").andOnUiThread(this::onBackPressed);
                return;
            }
            ImageDialog dialog = new ImageDialog(getContext());
            dialog.setOkText("上传");
            new Thread(() -> {
                if (!TextUtils.isEmpty(mShareFileType)) {
                    if (mShareFileType.startsWith("image")) {
                        try (InputStream inputStream = getContentResolver().openInputStream(mShareFileUri)) {
                            byte[] data = InputStreamUtils.readStream(inputStream);
                            dialog.loadImage(data);
                        } catch (Exception e) {
                            Log.e(TAG, e.getMessage(), e);
                        }
                    }
                }
            }).start();
            dialog.setOnOk(v -> {
                AndPermission.with(getContext())
                        .permission(Manifest.permission.READ_EXTERNAL_STORAGE)
                        .rationale((context, permissions, executor) -> executor.execute())
                        .onGranted(permissions -> {
                            try (InputStream inputStream = getContentResolver().openInputStream(mShareFileUri)) {
                                String filePath = UriUtils.getFileAbsolutePath(getContext(), mShareFileUri);
                                byte[] data = InputStreamUtils.readStream(inputStream);
                                uploadFile(filePath, data);
                            } catch (Exception e) {
                                Log.e(TAG, e.getMessage(), e);
                            }
                        })
                        .onDenied(permissions -> {
                            IToast.fail(getContext(), "授权失败");
                        })
                        .start();
                dialog.dismiss();
            });
            dialog.show();
        });
    }

    private void getFileList(FileReceiverActivity.DataOperation operation) {
        List<Api.RequestParam> params = new ArrayList<>();
        params.add(new Api.RequestParam("page", String.valueOf(mPage)));
        params.add(new Api.RequestParam("limit", String.valueOf(PAGE_LIMIT)));
        params.add(new Api.RequestParam("parentId", currentDir.peek()));
        Api.get(getContext(), Apis.USER_FILE_LIST, params, new Api.ApiCallback() {
            @Override
            public void onFailure(Context context, Call call, IOException e) {
                Log.e(TAG, e.getMessage(), e);
            }

            @Override
            public void onResponse(Context context, Call call, Response response) throws IOException {
                String res = response.body().string();
                FileListResp resp = JSON.parseObject(res, FileListResp.class);
                if (resp != null && resp.getCode().equals(ApiStatusCode.OK)) {
                    List<FileItemVo> list = resp.getData();
                    flushData(operation, list);
                } else {
                    IToast.fail(getContext(), "用户未登录").andOnUiThread(() -> {
                        Intent loginIntent = new Intent(getContext(), LoginActivity.class);
                        startActivityForResult(loginIntent, LoginActivity.REQUEST_CODE);
                    });
                }
                closeLoading(operation);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == LoginActivity.REQUEST_CODE) {
            new Thread(() -> {
                boolean isLogin = data.getBooleanExtra(LoginActivity.CONFIRM_LOGIN_KEY, false);
                if (isLogin) {
                    getFileList(DataOperation.refresh);
                } else {
                    runOnUiThread(this::onBackPressed);
                }
            }).start();
        }
    }

    private void flushData(FileReceiverActivity.DataOperation operation, List<FileItemVo> list) {
        Log.i(TAG, operation.name());
        switch (operation) {
            case load:
                if (list == null || list.isEmpty()) {
                    mPage.decrementAndGet();
                }
                mAdapter.appendData(list);
                break;
            case refresh:
                mAdapter.flushData(list);
                runOnUiThread(() -> mRecyclerView.scrollToPosition(0));
                break;
        }
    }

    private void closeLoading(FileReceiverActivity.DataOperation operation) {
        switch (operation) {
            case refresh:
                mSmartRefreshLayout.finishRefresh(true);
                break;
            case load:
                mSmartRefreshLayout.finishLoadMore(true);
                break;
        }
    }

    private void uploadFile(String filePath, InputStream fileInputStream) throws IOException {
        uploadFile(filePath, InputStreamUtils.readStream(fileInputStream));
    }

    private void uploadFile(String filePath, byte[] data) {
        File file = new File(filePath);

        // 根据文件名获取文件类型
        FileTypeVo fileType = FileTypeUtils.fromContentType(getContext(), file.getName());

        List<Api.RequestParam> params = new ArrayList<>();
        params.add(new Api.RequestParam("parentId", currentDir.peek()));
        params.add(new Api.RequestParam("chunks", "1"));
        params.add(new Api.RequestParam("chunk", "0"));
        params.add(new Api.RequestParam("type", fileType.getTypeId()));
        Api.postFile(getContext(), Apis.UPLOAD_IMAGE, "file", file.getName(), data, params, new Api.ApiCallback() {
            @Override
            public void onFailure(Context context, Call call, IOException e) {
                Log.e(TAG, e.getMessage(), e);
                IToast.fail(getContext(), "上传失败");
            }

            @Override
            public void onResponse(Context context, Call call, Response response) throws IOException {
                IToast.success(getContext(), "上传成功");
            }
        });
    }
}